home *** CD-ROM | disk | FTP | other *** search
/ Amiga Packmags / Source, The - Issue 5 (1993)(Epsilon)[WB].zip / Source, The - Issue 5 (1993)(Epsilon)[WB].adf / Source / Vectors / VectorSpace / PointInPoly.lha / pointnpolygon.txt3 < prev   
Internet Message Format  |  1989-10-24  |  6KB

  1. From albanycs!leah:rsb584 Tue Mar  1 15:54:24 1988
  2. Received: by albanycs.albany.edu (5.54/4.8)
  3.     id AA11798; Tue, 1 Mar 88 15:48:08 EST
  4. Date: Tue, 1 Mar 88 15:48:05 EST
  5. From: albanycs!leah:rsb584 (Raymond S Brand)
  6. Received: by leah.Albany.EDU (5.58/1.1)
  7.     id AA15407; Tue, 1 Mar 88 15:48:05 EST
  8. Message-Id: <8803012048.AA15407@leah.Albany.EDU>
  9. To: albanycs:beowulf!rsbx
  10. Subject: winding.num.txt
  11.  
  12. >From kenm@sci.UUCP Sat Feb 27 19:21:05 1988
  13. Path: leah!uwmcsd1!tut.cis.ohio-state.edu!mailrus!nrl-cmf!ames!oliveb!pyramid!voder!tolerant!sci!kenm
  14. From: kenm@sci.UUCP (Ken McElvain)
  15. Newsgroups: comp.graphics,comp.sys.ibm.pc
  16. Subject: Re: point-in-polygon again
  17. Summary: point in poly by winding number
  18. Keywords: READ THIS ONLY IF YOUR IQ <<125
  19. Message-ID: <16460@sci.UUCP>
  20. Date: 28 Feb 88 00:21:05 GMT
  21. References: <971@ut-emx.UUCP> <20533@amdcad.AMD.COM> <7626@pur-ee.UUCP> <5305@spool.cs.wisc.edu>
  22. Distribution: na
  23. Organization: Silicon Compilers Systems Corp. San Jose, Ca
  24. Lines: 132
  25.  
  26. In article <5305@spool.cs.wisc.edu>, planting@speedy.cs.wisc.edu (W. Harry Plantinga) writes:
  27. > In article <7626@pur-ee.UUCP> beatyr@pur-ee.UUCP (Robert Beaty) writes:
  28. > >In article <20533@amdcad.AMD.COM> msprick@amdcad.UUCP (Rick Dorris) writes:
  29. > >>In article <971@ut-emx.UUCP> jezebel@ut-emx.UUCP (Jim @ MAC) writes:
  30. > >>>Have a nice one here:
  31. > >>>Have a boundary defined on the screen. Boundary is composed of points
  32. > >>>joined by lines... Now some random points are generated and I want to check
  33. > >>>if a given point is within or outside the existing boundary.. Any algorithm for
  34. > >> <rick suggests the infinite ray/intersection counting algorithm>
  35. > >
  36. > >I have seen this type of algorithm before and the one I thought up
  37. > >in an afternoon is FAR surperior and vastly simpler to code up.
  38. > >
  39. > ><robert beaty suggests an algorithm that measures sums the angles of
  40. > >the lines connecting the poitns and the test point>
  41. > Haven't I seen this discussion of point-in-polygon algorithms about 15
  42. > times before? :-)
  43. > Robert, your algorithm is simpler only in the kind of problems it
  44. > handles.  It will only work for convex polygons, whereas the other
  45. > works for any polygons.  It's not even much simpler; measuring angles
  46. > and determining whether line segments intersect are of comparable
  47. > difficulty.
  48. > Maybe you should have said that althogh your algorithm is far
  49. > inferior, it's not any easier to code?
  50.  
  51.  
  52. Robert's suggestion is a good one.  The sum of the angles about the
  53. test point is known as the winding number.  For non intersecting
  54. polygons if the winding number is non-zero then the test point is
  55. inside the polygon.  It works just fine for convex and concave
  56. polygon's.  Intersecting polygon's give reasonable results too.
  57. A figure 8  will give a negitive winding number for a test point
  58. in one of the loops and a positive winding number for the other loop,
  59. with all points outside having a winding number of 0.  Other advantages
  60. of the winding number calculation are that it does not suffer from
  61. the confusion of the infinite ray algorithm when the ray crosses a vertex
  62. or is colinear with an edge.
  63.  
  64. Here is my version of a point in poly routine using a quadrant
  65. granularity winding number.  The basic idea is to total the angle
  66. changes for a wiper arm with its origin at the point and whos end
  67. follows the polygon points.  If the angle change is 0 then you are
  68. outside, otherwise you are in some sense inside.  It is not necessary to
  69. compute exact angles, resolution to a quadrant is sufficient, greatly
  70. simplifying the calculations. 
  71.  
  72. I pulled this out of some other code and hopefully didn't break it in
  73. doing so.  There is some ambiguity in this version as to whether a point
  74. lying on the polygon is inside or out.  This can be fairly easily
  75. detected though, so you can do what you want in that case. 
  76.  
  77.  
  78. -----------------------------------------------------------------
  79. /*
  80.  * Quadrants:
  81.  *    1 | 0
  82.  *    -----
  83.  *    2 | 3
  84.  */
  85.  
  86. typedef struct  {
  87.         int x,y;
  88. } point;
  89.  
  90. pointinpoly(pt,cnt,polypts)
  91. point pt;       /* point to check */
  92. int cnt;        /* number of points in poly */
  93. point *polypts; /* array of points, */
  94.                 /* last edge from polypts[cnt-1] to polypts[0] */
  95. {
  96.         int oldquad,newquad;
  97.         point thispt,lastpt;
  98.         int a,b;
  99.         int wind;       /* current winding number */
  100.  
  101.         wind = 0;
  102.         lastpt = polypts[cnt-1];
  103.         oldquad = whichquad(lastpt,pt); /* get starting angle */
  104.         for(i=0;i<cnt;i++) { /* for each point in the polygon */
  105.                 thispt = polypts[i];
  106.                 newquad = whichquad(thispt,pt);
  107.                 if(oldquad!=newquad) { /* adjust wind */
  108.                         /*
  109.                          * use mod 4 comparsions to see if we have
  110.                          * advanced or backed up one quadrant 
  111.                          */
  112.                         if(((oldquad+1)&3)==newquad) wind++;
  113.                         else if((((newquad+1)&3)==oldquad) wind--;
  114.                         else {
  115.                                 /*
  116.                                  * upper left to lower right, or
  117.                                  * upper right to lower left. Determine
  118.                                  * direction of winding  by intersection
  119.                                  *  with x==0.
  120.                                  */
  121.                                 a = lastpt.y - thispt.y;
  122.                                 a *= (pt.x - lastpt.x);
  123.                                 b = lastpt.x - thispt.x;
  124.                                 a += lastpt.y * b;
  125.                                 b *= pt.y;
  126.  
  127.                                 if(a > b) wind += 2;
  128.                                 else wind -= 2;
  129.                         }
  130.                 }
  131.                 lastpt = thispt;
  132.         }
  133.         return(wind); /* non zero means point in poly */
  134. }
  135.  
  136. /*
  137.  * Figure out which quadrent pt is in with respect to orig
  138.  */
  139. int whichquad(pt,orig)
  140. point pt;
  141. point orig;
  142. {
  143.         if(pt.x < orig.x) {
  144.                 if(pt.y < orig.y) quad = 2;
  145.                 else quad = 1;
  146.         } else {
  147.                 if(pt.y < orig.y) quad = 3;
  148.                 else quad = 0;
  149.         }
  150. }
  151.  
  152.  
  153. Ken McElvain
  154. decwrl!sci!kenm
  155.  
  156.  
  157.